package com.pine.common.systemlog.config;

import com.pine.common.beans.LogId;
import com.pine.common.systemlog.SysLogVo;
import com.pine.common.systemlog.aspect.SystemLogAspect;
import com.pine.common.systemlog.event.SysLogEventListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * 系统日志自动配置类
 *
 * @author pine manage
 * @since 2024-08-12
 */
@Configuration
@Slf4j
@EnableAsync
@ConditionalOnWebApplication
@ConditionalOnProperty(name = {"pine.common.system-log.enable"}, havingValue = "true")
@EnableConfigurationProperties({SystemLogProperties.class})
public class SystemLogAutoConfiguration {

    @Bean
    @Order(100)
    @ConditionalOnMissingBean(SystemLogAspect.class)
    public SystemLogAspect systemLogAspect() {
        return new SystemLogAspect();
    }

    @Bean
    @ConditionalOnMissingBean
    public SysLogEventListener sysLogEventListener() {
        List<Consumer<SysLogVo>> consumers = new ArrayList<>();
        consumers.add(vo -> {
            LogId.put(vo.getLogId());
            log.info("system-log:{}", vo);
        });
        return new SysLogEventListener(consumers);
    }

    @Bean(name = "sysLogEventListenerExecutor")
    public Executor sysLogEventListenerExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(1000);
        executor.initialize();
        return executor;
    }

}
